﻿using System.Collections.Generic;
using ImageProcessing.Common;

namespace ImageProcessing
{
    internal class RegionSelect
    {
        private readonly List<InterestPoint> _regionPoints;
        readonly AntiClockWiseSorter _antiClockWiseSorter = new AntiClockWiseSorter();

        public IEnumerable<InterestPoint> RegionPoints
        {
            get { return _regionPoints.AsReadOnly(); }
        }

        private readonly int _regionPointsCount;

        public RegionSelect(List<InterestPoint> regionPoints)
        {
            var convexHull = ConvexHull.GetBoundedPoints(regionPoints);
            _regionPoints = _antiClockWiseSorter.SortedList(convexHull);
            _regionPointsCount = _regionPoints.Count;
        }

        public List<InterestPoint> GetPointsWithinRegionOfImage(List<InterestPoint> imagePoints)
        {
            var result = new List<InterestPoint>();

            for (int index = 0; index < imagePoints.Count; index++)
            {
                InterestPoint interestPoint = imagePoints[index];

                if (PointInPolygon(interestPoint))
                    result.Add(interestPoint);
            }

            return result;
        }


        private bool PointInPolygon(InterestPoint point)
        {
            var j = _regionPointsCount - 1;
            var oddNodes = false;

            for (int i = 0; i < _regionPointsCount; i++)
            {
                if (_regionPoints[i].Y < point.Y && _regionPoints[j].Y >= point.Y ||
                    _regionPoints[j].Y < point.Y && _regionPoints[i].Y >= point.Y)
                {
                    if (_regionPoints[i].X + (point.Y - _regionPoints[i].Y) / (_regionPoints[j].Y - _regionPoints[i].Y) *
                                             (_regionPoints[j].X - _regionPoints[i].X) < point.X)
                    {
                        oddNodes = !oddNodes;
                    }
                }
                j = i;
            }

            return oddNodes;
        }
    }
}